<template>
  <LeftAndRight>
    <!--左边部分-->
    <template #left-content>
      <!--搜索-->
      <div class="top-search">
        <el-input placeholder="搜索" size="small" v-model="searchKey" clearable />
      </div>
      <!--用户会话列表-->
      <div class="chat-user-list">
        <div v-for="data in chatUserList" v-show="data.contactName.includes(searchKey)">
          <ChatUser
            :data="data"
            @click="chatUserClickHandler(data)"
            :currentChatUser="data.contactId === currentChatUser.contactId"
            @contextmenu.prevent="onContextMenu(data, $event)"
          />
        </div>
      </div>
    </template>
    <!--右边部分-->
    <template #right-content>
      <!--头部用户名称或者群组名称（群人数）-->
      <div class="top">
        <!--联系人名称-->
        <div class="title-panel" v-if="Object.keys(currentChatUser).length > 0">
          <div class="title">
            <span>{{ currentChatUser.contactName }}</span>
            <span v-if="currentChatUser.contactType == 1 && currentChatUser.disable !== 1"
              >({{ currentChatUser.memberCount }})</span
            >
          </div>
        </div>
        <!--更多-->
        <div
          v-if="currentChatUser.contactType == 1 && currentChatUser.disable !== 1"
          class="iconfont icon-gengduo"
          @click="showGroupDetail"
        ></div>
      </div>
      <!--具体用户会话记录列表-->
      <div
        class="chat-panel"
        v-show="Object.keys(currentChatUser).length > 0"
        @mouseenter="updateReadPrivateMsgState"
      >
        <!--置顶消息-->
        <div class="top-message">
          <div
            class="top-message-inner"
            v-if="topMsg && topMsg.chatId === currentChatUser.chatId"
          >
            <div
              class="top-message-left"
              @click="getMessageContent(topMsg)"
              v-if="topMsg.messageType === 'text' || topMsg.messageType === 'reply'"
            >
              置顶消息：{{ topMsg.messageContent }}
            </div>
            <div
              class="top-message-left"
              @click="getMessageContent(topMsg)"
              v-if="topMsg.messageType === 'image'"
            >
              置顶消息：[图片]
            </div>
            <div
              class="top-message-left"
              @click="getMessageContent(topMsg)"
              v-if="topMsg.messageType === 'video'"
            >
              置顶消息：[视频]
            </div>
            <div
              class="top-message-left"
              @click="getMessageContent(topMsg)"
              v-if="topMsg.messageType === 'file'"
            >
              置顶消息：[文件]
            </div>
            <div
              class="top-message-left"
              @click="getMessageContent(topMsg)"
              v-if="topMsg.messageType === 'voice'"
            >
              置顶消息：[语音]
            </div>
            <div class="top-message-right" @click="topRemove">
              <i class="iconfont icon-guanbi" />
            </div>
          </div>
        </div>
        <div class="message-panel" id="message-panel">
          <div
            class="message-item"
            v-for="(data, index) in messageList"
            :id="'message' + data.messageId"
          >
            <!--时间-->
            <template
              v-if="
                index > 1 &&
                data.sendTime - messageList[index - 1].sendTime >= 300000 &&
                data.messageType !== 'withdraw' &&
                data.messageType !== 'common' &&
                data.messageType !== 'add'
              "
            >
              <ChatMessageTime :data="data"></ChatMessageTime>
            </template>
            <!--通用消息-->
            <template
              v-if="
                data.messageType == 'common' ||
                data.messageType == 'withdraw' ||
                data.messageType == 'add'
              "
            >
              <ChatMessageCommon :data="data" />
            </template>
            <!--消息内容-->
            <template
              v-if="
                data.messageType == 'add' ||
                data.messageType == 'text' ||
                data.messageType == 'image' ||
                data.messageType == 'video' ||
                data.messageType == 'file' ||
                data.messageType == 'voice' ||
                data.messageType == 'reply'
              "
            >
              <ChatMessageItem
                :data="data"
                :currentChatUser="currentChatUser"
                @contextmenu.prevent="onContextMenuMessage(data, $event)"
                @reloadReply="getReloadReply(data)"
              />
            </template>
          </div>
        </div>
        <!--发送消息框-->
        <MessageSend
          :currentChatUser="currentChatUser"
          ref="messageSendRef"
          v-if="currentChatUser.disable !== 1"
        />
      </div>
      <!--空白区域-->
      <div v-show="Object.keys(currentChatUser).length == 0">
        <Blank></Blank>
      </div>
    </template>
  </LeftAndRight>
  <!--群组信息-->
  <ChatGroup ref="chatGroupDetailRef" />
  <!--回复信息详情-->
  <MessageReplyDetail ref="messageReplyDetailRef" />
  <!--置顶信息详情-->
  <MessageTopDetail ref="messageTopDetailRef" />
  <!--删除会话-->
  <DeleteChat ref="deleteChatRef" @reload="reload" />
  <!--清空会话-->
  <ClearChat ref="clearChatRef" @clearReload="clearReload" />
</template>

<!--setup语法问题(保持路由激活)-->
<script>
export default {
  name: "chat",
};
</script>

<script setup>
import ChatUser from "./ChatUser.vue";
import ChatMessageTime from "./ChatMessageTime.vue";
import ChatMessageCommon from "./ChatMessageCommon.vue";
import ChatMessageItem from "./ChatMessageItem.vue";
import Blank from "@/components/Blank.vue";
import ChatGroup from "./ChatGroup.vue";
import MessageSend from "./MessageSend.vue";
import { ref, getCurrentInstance, nextTick, onMounted, watch } from "vue";
import {
  openIndexedDB,
  getAllData,
  getDataByKey,
  getData,
  updateDB,
  deleteDB,
  cursorDelete,
  getDataByIndexAndPage,
} from "@/utils/IndexedDB";
import { useUserInfoStore } from "@/stores/UserInfoStore";
import { useMessageCountStore } from "@/stores/MessageCountStore";
import { useRoute, useRouter } from "vue-router";
import { useFriendDeleteVisibleStore } from "@/stores/FriendDeleteStore";
import ContextMenu from "@imengyu/vue3-context-menu";
import "@imengyu/vue3-context-menu/lib/vue3-context-menu.css";
import { useReplyMsgVisibleStore } from "@/stores/ReplyMsgVisibleStore";
import MessageReplyDetail from "./MessageReplyDetail.vue";
import MessageTopDetail from "./MessageTopDetail.vue";
import DeleteChat from "./DeleteChat.vue";
import ClearChat from "./ClearChat.vue";

const userInfoStore = useUserInfoStore();
const messageCountStore = useMessageCountStore();
const { proxy } = getCurrentInstance();
const route = useRoute();
const router = useRouter();
const friendDeleteStore = useFriendDeleteVisibleStore();
const replyMsgStore = useReplyMsgVisibleStore();

//ws转发的消息
const getMessage = () => {
  proxy.WebSocket.onMessage(async (message) => {
    // console.log("ws转发的消息：", message);
    //获取db实列
    let chatDb = await openIndexedDB(
      "chat" + JSON.parse(localStorage.getItem("userInfo")).userId
    );
    switch (message.commandCode) {
      case 10000: //初始化ws
        //加载用户会话
        getChatUserList();
        //加载联系人申请
        loadContactApply();
        //删除会话
        if (message.data.chatIdList.length !== 0) {
          message.data.chatIdList.forEach(async (chatId) => {
            //查询要删除的会话
            const chatUserItem = chatUserList.value.find((item) => {
              return item.chatId == chatId;
            });
            //修改会话为删除状态
            const setChatUserDelete = await getDataByKey(
              chatDb,
              "chatUser",
              chatUserItem.contactId
            );
            setChatUserDelete.status = 2;
            updateDB(chatDb, "chatUser", setChatUserDelete);
            //删除聊天记录
            cursorDelete(chatDb, "message", "chatId", chatId);
            //会话列表过滤
            chatUserList.value = chatUserList.value.filter((item) => {
              return item.chatId !== chatId;
            });
          });
        }
        //清空会话
        if (message.data.clearChatIdList.length !== 0) {
          message.data.clearChatIdList.forEach(async (chatId) => {
            //查询要删除的会话
            const chatUserItem = chatUserList.value.find((item) => {
              return item.chatId == chatId;
            });
            const setChatUserClear = await getDataByKey(
              chatDb,
              "chatUser",
              chatUserItem.contactId
            );
            setChatUserClear.clean = 2;
            setChatUserClear.lastMessage = "已清空聊天记录";
            setChatUserClear.lastReceiveTime = new Date().getTime();
            updateDB(chatDb, "chatUser", setChatUserClear);
            //删除聊天记录
            cursorDelete(chatDb, "message", "chatId", chatId);
          });
        }
        break;
      case 10005: //处理私聊消息应答(自己发送的消息)
        //过滤撤回消息
        if (message.data.withdrawId) {
          messageList.value = messageList.value.filter((item) => {
            return item.messageId !== message.data.withdrawId;
          });
        }
        //设置未读
        message.data.msgState = 1;
        messageList.value.push(message.data);
        gotoBottom();
        //刷新用户会话列表
        const sendChatUser = chatUserList.value.find((item) => {
          return item.chatId == message.data.chatId;
        });
        if (sendChatUser) {
          sendChatUser.lastReceiveTime = message.data.sendTime;
          if (message.data.messageType === "image") {
            sendChatUser.lastMessage = "[图片]";
          } else if (
            message.data.messageType === "text" ||
            message.data.messageType === "reply"
          ) {
            sendChatUser.lastMessage = message.data.messageContent;
          } else if (message.data.messageType === "video") {
            sendChatUser.lastMessage = "[视频]";
          } else if (message.data.messageType === "file") {
            sendChatUser.lastMessage = "[文件]";
          } else if (message.data.messageType === "voice") {
            sendChatUser.lastMessage = "[语音]";
          } else if (message.data.messageType === "withdraw") {
            sendChatUser.lastMessage =
              "`" + message.data.sendUsername + "`" + " " + "撤回了一条消息";
          }
        } else {
          //如果是删除状态或者清空消息状态，重新设置为正常状态
          const setChatUserDelete = await getDataByKey(
            chatDb,
            "chatUser",
            message.data.contactId
          );
          setChatUserDelete.status = 1;
          setChatUserDelete.clean = 1;
          updateDB(chatDb, "chatUser", setChatUserDelete);
          //重新添加到会话列表
          const chatUser = {};
          chatUser.userId = userInfoStore.getInfo().userId;
          chatUser.contactId = message.data.contactId;
          chatUser.contactType = message.data.contactType;
          chatUser.chatId = message.data.chatId;
          chatUser.contactName = message.data.contactUsername;
          chatUser.contactIcon = message.data.contactUserIcon;
          chatUser.lastMessage = message.data.messageContent;
          chatUser.lastReceiveTime = message.data.sendTime;
          chatUser.topType = 0;
          chatUser.status = 1;
          chatUser.clean = 1;
          chatUserList.value.unshift(chatUser);
        }
        sortChatUserList(chatUserList.value);
        break;
      case 10006: //处理私聊消息(对方发送的消息)
        //构建会话
        const chatUser = {};
        chatUser.userId = userInfoStore.getInfo().userId;
        chatUser.contactId = message.data.sendUserId;
        chatUser.contactType = message.data.contactType;
        chatUser.chatId = message.data.chatId;
        chatUser.contactName = message.data.sendUsername;
        chatUser.contactIcon = message.data.sendUserIcon;
        chatUser.lastMessage = message.data.messageContent;
        chatUser.lastReceiveTime = message.data.sendTime;
        chatUser.topType = 0;
        chatUser.noReadCount = 1;
        //查询是否有当前会话
        const reciverChatUser = chatUserList.value.find((item) => {
          return item.chatId == message.data.chatId;
        });
        //没有及追加上去有就变更
        if (reciverChatUser == null) {
          chatUserList.value.unshift(chatUser);
        } else {
          reciverChatUser.lastReceiveTime = message.data.sendTime;
          if (message.data.chatId !== currentChatUser.value.chatId) {
            reciverChatUser.noReadCount = 1 + reciverChatUser.noReadCount;
            const setChatUserClear = await getDataByKey(
              chatDb,
              "chatUser",
              reciverChatUser.contactId
            );
            setChatUserClear.noReadCount = 1 + setChatUserClear.noReadCount;
            updateDB(chatDb, "chatUser", setChatUserClear);
          }
          if (message.data.messageType === "image") {
            reciverChatUser.lastMessage = "[图片]";
          } else if (
            message.data.messageType === "text" ||
            message.data.messageType === "reply"
          ) {
            reciverChatUser.lastMessage = message.data.messageContent;
          } else if (message.data.messageType === "video") {
            reciverChatUser.lastMessage = "[视频]";
          } else if (message.data.messageType === "file") {
            reciverChatUser.lastMessage = "[文件]";
          } else if (message.data.messageType === "voice") {
            reciverChatUser.lastMessage = "[语音]";
          } else if (message.data.messageType === "withdraw") {
            reciverChatUser.lastMessage =
              "`" + message.data.sendUsername + "`" + " " + "撤回了一条消息";
          }
        }
        //未读数和追加消息
        if (message.data.chatId !== currentChatUser.value.chatId) {
          messageCountStore.setCount("chatCount", 1, false);
        } else {
          Object.assign(currentChatUser.value, chatUser);
          //过滤撤回消息
          messageList.value = messageList.value.filter((item) => {
            return item.messageId !== message.data.withdrawId;
          });
          messageList.value.push(message.data);
          gotoBottom();
        }
        //重新排序
        sortChatUserList(chatUserList.value);
        break;
      case 10007: //处理群聊消息应答(自己发送的消息)
        //过滤撤回消息
        if (message.data.withdrawId) {
          messageList.value = messageList.value.filter((item) => {
            return item.messageId !== message.data.withdrawId;
          });
        }
        messageList.value.push(message.data);
        gotoBottom();
        //刷新用户会话列表
        const sendGroupChatUser = chatUserList.value.find((item) => {
          return item.chatId == message.data.chatId;
        });
        if (sendGroupChatUser) {
          sendGroupChatUser.lastReceiveTime = message.data.sendTime;
          if (
            message.data.messageType === "withdraw" ||
            message.data.messageType === "common"
          ) {
            sendGroupChatUser.lastSendName = "";
          } else {
            sendGroupChatUser.lastSendName = message.data.sendUsername;
          }
          if (message.data.messageType === "image") {
            sendGroupChatUser.lastMessage = "[图片]";
          } else if (
            message.data.messageType === "text" ||
            message.data.messageType === "reply"
          ) {
            sendGroupChatUser.lastMessage = message.data.messageContent;
          } else if (message.data.messageType === "video") {
            sendGroupChatUser.lastMessage = "[视频]";
          } else if (message.data.messageType === "file") {
            sendGroupChatUser.lastMessage = "[文件]";
          } else if (message.data.messageType === "voice") {
            sendGroupChatUser.lastMessage = "[语音]";
          } else if (message.data.messageType === "withdraw") {
            sendGroupChatUser.lastMessage =
              "`" + message.data.sendUsername + "`" + " " + "撤回了一条消息";
          }
        } else {
          //如果是删除状态或者清空消息状态，重新设置为正常状态
          const setChatUserDelete = await getDataByKey(
            chatDb,
            "chatUser",
            message.data.contactId
          );
          setChatUserDelete.status = 1;
          setChatUserDelete.clean = 1;
          updateDB(chatDb, "chatUser", setChatUserDelete);
          //重新添加到会话列表
          const chatUser = {};
          chatUser.userId = userInfoStore.getInfo().userId;
          chatUser.contactId = message.data.contactId;
          chatUser.contactType = message.data.contactType;
          chatUser.chatId = message.data.chatId;
          chatUser.contactName = message.data.contactUsername;
          chatUser.contactIcon = message.data.contactUserIcon;
          chatUser.lastMessage = message.data.messageContent;
          chatUser.lastReceiveTime = message.data.sendTime;
          chatUser.memberCount = message.data.memberCount;
          chatUser.lastSendName = message.data.sendUsername;
          chatUser.topType = 0;
          chatUser.status = 1;
          chatUser.clean = 1;
          chatUserList.value.unshift(chatUser);
        }
        sortChatUserList(chatUserList.value);
        break;
      case 10008: //处理群聊消息(对方发送的消息)
        //构建会话
        const chatUserGroup = {};
        chatUserGroup.userId = userInfoStore.getInfo().userId;
        chatUserGroup.contactId = message.data.contactId;
        chatUserGroup.contactType = message.data.contactType;
        chatUserGroup.chatId = message.data.chatId;
        chatUserGroup.contactName = message.data.contactUsername;
        chatUserGroup.contactIcon = message.data.contactUserIcon;
        chatUserGroup.lastMessage = message.data.messageContent;
        chatUserGroup.lastReceiveTime = message.data.sendTime;
        chatUserGroup.topType = 0;
        chatUserGroup.noReadCount = 1;
        chatUserGroup.memberCount = message.data.memberCount;
        chatUserGroup.status = 1;
        chatUserGroup.clean = 1;
        if (
          message.data.messageType === "withdraw" ||
          message.data.messageType === "common"
        ) {
          chatUserGroup.lastSendName = "";
        } else {
          chatUserGroup.lastSendName = message.data.sendUsername;
        }
        //查询是否有当前会话
        const reciverChatUserGroup = chatUserList.value.find((item) => {
          return item.chatId == message.data.chatId;
        });
        //没有及追加上去有就变更
        if (reciverChatUserGroup == null) {
          chatUserList.value.unshift(chatUserGroup);
        } else {
          reciverChatUserGroup.lastReceiveTime = message.data.sendTime;
          if (
            message.data.messageType === "withdraw" ||
            message.data.messageType === "common"
          ) {
            reciverChatUserGroup.lastSendName = "";
          } else {
            reciverChatUserGroup.lastSendName = message.data.sendUsername;
          }
          if (message.data.chatId !== currentChatUser.value.chatId) {
            reciverChatUserGroup.noReadCount = 1 + reciverChatUserGroup.noReadCount;
            const setChatUserClear = await getDataByKey(
              chatDb,
              "chatUser",
              reciverChatUserGroup.contactId
            );
            setChatUserClear.noReadCount = 1 + setChatUserClear.noReadCount;
            updateDB(chatDb, "chatUser", setChatUserClear);
          }
          if (message.data.messageType === "image") {
            reciverChatUserGroup.lastMessage = "[图片]";
          } else if (
            message.data.messageType === "text" ||
            message.data.messageType === "reply"
          ) {
            reciverChatUserGroup.lastMessage = message.data.messageContent;
          } else if (message.data.messageType === "video") {
            reciverChatUserGroup.lastMessage = "[视频]";
          } else if (message.data.messageType === "file") {
            reciverChatUserGroup.lastMessage = "[文件]";
          } else if (message.data.messageType === "voice") {
            reciverChatUserGroup.lastMessage = "[语音]";
          } else if (message.data.messageType === "withdraw") {
            reciverChatUserGroup.lastMessage =
              "`" + message.data.sendUsername + "`" + " " + "撤回了一条消息";
          }
        }
        //未读数和追加消息
        if (message.data.chatId !== currentChatUser.value.chatId) {
          messageCountStore.setCount("chatCount", 1, false);
        } else {
          Object.assign(currentChatUser.value, chatUserGroup);
          //过滤撤回消息
          messageList.value = messageList.value.filter((item) => {
            return item.messageId !== message.data.withdrawId;
          });
          messageList.value.push(message.data);
          gotoBottom();
        }
        //重新排序
        sortChatUserList(chatUserList.value);
        break;
      case 10016: //消息已读
        for (let i = 0; i < messageList.value.length; i++) {
          messageList.value[i].msgState = 2;
        }
        break;
      case 10001: //申请添加好友/群组
        loadContactApply();
        break;
      case 10002: //申请添加好友/群组
        const addContact = {};
        addContact.contactId = message.data.contactId;
        addContact.contactType = message.data.contactType;
        addContact.chatId = message.data.chatId;
        addContact.contactName = message.data.contactUsername;
        addContact.contactIcon = message.data.contactUserIcon;
        addContact.lastMessage = message.data.messageContent;
        addContact.lastReceiveTime = message.data.sendTime;
        addContact.noReadCount = 1;
        if (message.data.contactType === 0) {
          addContact.memberCount = 0;
        } else if (message.data.contactType === 1) {
          addContact.memberCount = message.data.memberCount;
        }
        if (message.data.messageType === "common") {
          addContact.lastSendName = null;
        } else {
          addContact.lastSendName = message.data.sendUsername;
        }
        const addContactChatUser = chatUserList.value.find((item) => {
          return item.chatId == message.data.chatId;
        });
        if (addContactChatUser == null) {
          chatUserList.value.unshift(addContact);
        } else {
          addContactChatUser.lastMessage = message.data.messageContent;
          addContactChatUser.lastReceiveTime = message.data.sendTime;
          addContactChatUser.memberCount = message.data.memberCount;
          if (message.data.messageType === "common") {
            addContact.lastSendName = null;
          } else {
            addContact.lastSendName = message.data.sendUsername;
          }
          if (message.data.chatId !== currentChatUser.value.chatId) {
            addContactChatUser.noReadCount = 1 + addContactChatUser.noReadCount;
          }
        }
        //未读数
        if (message.data.chatId !== currentChatUser.value.chatId) {
          messageCountStore.setCount("chatCount", 1, false);
        } else {
          Object.assign(currentChatUser.value, addContact);
          messageList.value.push(message.data);
          gotoBottom();
        }
        sortChatUserList(chatUserList.value);
        break;
      case 10003: //申请添加好友/群组
        const addReciverContact = {};
        addReciverContact.contactId = message.data.sendUserId;
        addReciverContact.contactType = message.data.contactType;
        addReciverContact.chatId = message.data.chatId;
        addReciverContact.contactName = message.data.sendUsername;
        addReciverContact.contactIcon = message.data.sendUserIcon;
        addReciverContact.lastMessage = message.data.messageContent;
        addReciverContact.lastReceiveTime = message.data.sendTime;
        addReciverContact.noReadCount = 1;
        if (message.data.contactType === 0) {
          addReciverContact.memberCount = 0;
        } else if (message.data.contactType === 1) {
          addReciverContact.memberCount = message.data.memberCount;
        }
        const addReciverContactChatUser = chatUserList.value.find((item) => {
          return item.chatId == message.data.chatId;
        });
        if (addReciverContactChatUser == null) {
          chatUserList.value.unshift(addReciverContact);
        } else {
          addReciverContactChatUser.lastMessage = message.data.messageContent;
          addReciverContactChatUser.lastReceiveTime = message.data.sendTime;
          addReciverContactChatUser.memberCount = message.data.memberCount;
          if (message.data.chatId !== currentChatUser.value.chatId) {
            addReciverContactChatUser.noReadCount =
              1 + addReciverContactChatUser.noReadCount;
          }
        }
        //未读数
        if (message.data.chatId !== currentChatUser.value.chatId) {
          messageCountStore.setCount("chatCount", 1, false);
        } else {
          Object.assign(currentChatUser.value, addReciverContact);
          messageList.value.push(message.data);
          gotoBottom();
        }
        sortChatUserList(chatUserList.value);
        break;
      case 10009: // 创建群组
        const chatUserCreateGroup = {};
        chatUserCreateGroup.contactId = message.data.contactId;
        chatUserCreateGroup.contactType = message.data.contactType;
        chatUserCreateGroup.chatId = message.data.chatId;
        chatUserCreateGroup.contactName = message.data.contactUsername;
        chatUserCreateGroup.contactIcon = message.data.contactUserIcon;
        chatUserCreateGroup.lastMessage = message.data.messageContent;
        chatUserCreateGroup.lastReceiveTime = message.data.sendTime;
        chatUserCreateGroup.noReadCount = 1;
        chatUserCreateGroup.memberCount = 1;
        chatUserCreateGroup.disable = 0;
        chatUserCreateGroup.status = 1;
        chatUserCreateGroup.clean = 1;
        chatUserCreateGroup.topType = 0;
        messageCountStore.setCount(
          "chatCount",
          messageCountStore.getCount("chatCount") + 1,
          true
        );
        chatUserList.value.unshift(chatUserCreateGroup);
        sortChatUserList(chatUserList.value);
        break;
      case 10010: //加入群组
      case 10011: //解散群组
      case 10012: //退出群组
      case 10013: //踢出群组
        const add = {};
        add.contactId = message.data.contactId;
        add.contactType = message.data.contactType;
        add.chatId = message.data.chatId;
        add.contactName = message.data.contactUsername;
        add.contactIcon = message.data.contactUserIcon;
        add.lastMessage = message.data.messageContent;
        add.lastReceiveTime = message.data.sendTime;
        add.memberCount = message.data.memberCount;
        add.noReadCount = 1;
        add.disable = 0;
        if (message.commandCode == 10011) {
          add.disable = 1;
        }
        const addChatUser = chatUserList.value.find((item) => {
          return item.chatId == message.data.chatId;
        });
        if (addChatUser == null) {
          chatUserList.value.unshift(add);
        } else {
          addChatUser.lastMessage = message.data.messageContent;
          addChatUser.lastReceiveTime = message.data.sendTime;
          addChatUser.memberCount = message.data.memberCount;
          addChatUser.lastSendName = "";
          if (message.commandCode == 10011) {
            addChatUser.disable = 1;
          }
          if (message.data.chatId !== currentChatUser.value.chatId) {
            addChatUser.noReadCount = 1 + addChatUser.noReadCount;
          }
        }
        //未读数
        if (message.data.chatId !== currentChatUser.value.chatId) {
          messageCountStore.setCount("chatCount", 1, false);
        } else {
          Object.assign(currentChatUser.value, add);
          messageList.value.push(message.data);
          gotoBottom();
        }
        sortChatUserList(chatUserList.value);
        break;
      case 10017: //私聊消息置顶
      case 10018: //群聊消息置顶
        if (currentChatUser.value.chatId == message.data.chatId) {
          topMsg.value = message.data;
        }
        break;
      case 10015: //删除用户会话
        const deleteChatUser = chatUserList.value.find((item) => {
          return item.chatId == message.data.chatId;
        });
        if (deleteChatUser.chatId == currentChatUser.value.chatId) {
          currentChatUser.value = {};
        }
        chatUserList.value = chatUserList.value.filter((item) => {
          return item.chatId !== message.data.chatId;
        });
        messageCountStore.setCount("chatCount", -deleteData.value.noReadCount, true);
        sortChatUserList(chatUserList.value);
        break;
      case 10019: //清空用户会话
        const clearChatUser = chatUserList.value.find((item) => {
          return item.chatId == message.data.chatId;
        });
        if (clearChatUser.chatId == currentChatUser.value.chatId) {
          currentChatUser.value = {};
        }
        clearChatUser.lastSendName = "";
        clearChatUser.lastMessage = "已清空聊天记录";
        clearChatUser.lastReceiveTime = new Date().getTime();
        messageCountStore.setCount("chatCount", -deleteData.value.noReadCount, true);
        sortChatUserList(chatUserList.value);
        break;
      case 10004: //用户名称/头像修改
      case 10014: //群组名称/头像修改
        const contactChatUser = chatUserList.value.find((item) => {
          return item.contactId == message.data.contactId;
        });
        contactChatUser.contactIcon = message.data.icon;
        contactChatUser.contactName = message.data.name;
        if (contactChatUser.chatId == currentChatUser.value.chatId) {
          currentChatUser.value.contactName = message.data.name;
        }
        break;
      case 10020: //强制下线
        proxy.Confirm({
          message: "您在其他地方已登录，被强制下线",
          okfun: () => {
            router.push("/login");
          },
          okText: "强制下线",
        });
        proxy.Api.logout();
        proxy.WebSocket.closeWs();
        localStorage.removeItem("userInfo");
        localStorage.removeItem("token");
        break;
    }
  });
};

//搜索关键字
const searchKey = ref("");

//用户会话列表数据
const chatUserList = ref([]);
//获取用户会话列表
const getChatUserList = async () => {
  let chatDb = await openIndexedDB(
    "chat" + JSON.parse(localStorage.getItem("userInfo")).userId
  );
  const data = await getAllData(chatDb, "chatUser");
  //设置未读数
  let noReadCount = 0;
  data.forEach((element) => {
    noReadCount = noReadCount + element.noReadCount;
  });
  messageCountStore.setCount("chatCount", noReadCount, true);
  //设置排序
  sortChatUserList(data);
  chatUserList.value = data;
  //会话为删除状态的不显示
  chatUserList.value = chatUserList.value.filter((item) => {
    return item.status == 1;
  });
  // console.log("会话用户数据：", chatUserList.value);
};

//排序
const sortChatUserList = (dataList) => {
  dataList.sort((a, b) => {
    const topTypeResult = b["topType"] - a["topType"];
    if (topTypeResult == 0) {
      return b["lastReceiveTime"] - a["lastReceiveTime"];
    }
    return topTypeResult;
  });
};

const messageSendRef = ref();
//当前用户会话
const currentChatUser = ref({});
//点击会话
const chatUserClickHandler = async (data) => {
  // console.log("点击的用户会话：", data);
  //当前的会话赋值
  currentChatUser.value = Object.assign({}, data);
  //获取IndexedDB实列
  let chatDb = await openIndexedDB(
    "chat" + JSON.parse(localStorage.getItem("userInfo")).userId
  );
  //复位分页
  page.pageNum = 1;
  //复位底部数据
  distanceBottom = 0;
  //先清空之前指定会话列表数据
  messageList.value = [];
  //分页查询
  getMessagePage(chatDb, data, 1);
  //清空输入框中的消息
  if (!proxy.Utils.isEmpty(messageSendRef.value)) {
    messageSendRef.value.cleanMessage();
  }
  //设置已读
  if (data.contactType === 0) {
    updateReadPrivateMsgState();
  }
  //清空指定消息记录数
  if (data.noReadCount !== 0) {
    messageCountStore.setCount("chatCount", -data.noReadCount, false);
    data.noReadCount = 0;
    const setChatUserClear = await getDataByKey(chatDb, "chatUser", data.contactId);
    setChatUserClear.noReadCount = 0;
    updateDB(chatDb, "chatUser", setChatUserClear);
  }
  //有回复消息的要清空
  replyMsgStore.setReplyMsg({});
  //查询置顶消息(有可能不在当前分页中，所以要全部查询)
  const messageListData = await getData(chatDb, "message", "chatId", data.chatId);
  const topMessage = messageListData.find((item) => {
    return item.msgTop == 2;
  });
  topMsg.value = topMessage;
};

//指定会话列表数据
const messageList = ref([]);
//分页查询
const page = {
  pageNum: 1,
};
const getMessagePage = async (chatDb, data, pageNum) => {
  //获取返回的数据
  const { list } = await getDataByIndexAndPage(
    chatDb,
    "message",
    "chatId",
    data.chatId,
    pageNum
  );
  //排序
  list.sort((a, b) => {
    return a.messageId - b.messageId;
  });
  //赋值
  messageList.value = list;
  // console.log("查询的指定会话列表数据：", messageList.value);
  //拉到底部
  gotoBottom();
};

//加载更多
const goToMore = async () => {
  //获取IndexedDB实列
  let chatDb = await openIndexedDB(
    "chat" + JSON.parse(localStorage.getItem("userInfo")).userId
  );
  page.pageNum = page.pageNum + 1;
  const { list } = await getDataByIndexAndPage(
    chatDb,
    "message",
    "chatId",
    currentChatUser.value.chatId,
    page.pageNum
  );
  //排序
  list.sort((a, b) => {
    return a.messageId - b.messageId;
  });
  if (list.length === 0) {
    proxy.$message.success("已是最早数据了...");
    return;
  }
  //追加数据
  messageList.value.unshift(...list);
  //分页
  const lastMessage = messageList.value[0];
  nextTick(() => {
    document.querySelector("#message" + lastMessage.messageId).scrollIntoView();
  });
};

//群详情
const chatGroupDetailRef = ref();
const showGroupDetail = () => {
  chatGroupDetailRef.value.show(currentChatUser.value.contactId);
};

//底部
let distanceBottom = 0;
const gotoBottom = () => {
  nextTick(() => {
    if (distanceBottom > 100) {
      return;
    }
    const feedItems = document.querySelectorAll(".message-item");
    if (feedItems.length > 0) {
      setTimeout(() => {
        feedItems[feedItems.length - 1].scrollIntoView();
      }, 100);
    }
  });
};

//设置消息已读
const updateReadPrivateMsgState = async () => {
  //如果消息则不执行
  if (currentChatUser.value.noReadCount === 0) {
    return;
  }
  //修改消息为已读
  await proxy.Api.updateReadMsgState(currentChatUser.value.contactId);
  //设置当前会话未读数为0，防止重复设置
  currentChatUser.value.noReadCount = 0;
};

//加载联系人
const loadContactApply = async () => {
  let chatDbUser = await openIndexedDB(
    "chat" + JSON.parse(localStorage.getItem("userInfo")).userId
  );
  const currentUserId = JSON.parse(localStorage.getItem("userInfo")).userId;
  const existCurrentUser = await getDataByKey(chatDbUser, "user", currentUserId);
  messageCountStore.setCount("contactApplyCount", existCurrentUser.contactNoRead, true);
};

//发送消息给联系人
const sendMessage = async (contactId) => {
  const sendChatUser = chatUserList.value.find((item) => {
    return item.contactId == contactId;
  });
  if (sendChatUser) {
    chatUserClickHandler(sendChatUser);
  } else {
    let chatDb = await openIndexedDB(
      "chat" + JSON.parse(localStorage.getItem("userInfo")).userId
    );
    const setChatUserItem = await getDataByKey(chatDb, "chatUser", contactId);
    chatUserClickHandler(setChatUserItem);
    return;
  }
};
//监听消息发送
watch(
  () => route.query.contactId,
  (newVal, oldVal) => {
    if (newVal && route.query.contactId) {
      sendMessage(route.query.contactId);
    }
  },
  { immediate: true, deep: true }
);

//监听删除拉黑好友操作则刷新好友列表
watch(
  () => friendDeleteStore.getFriendDelete(),
  () => {
    if (friendDeleteStore.getFriendDelete() == {}) {
      return;
    }
    const chatUserItem = chatUserList.value.find((item) => {
      return item.chatId == friendDeleteStore.getFriendDelete().chatId;
    });
    if (chatUserItem.chatId == friendDeleteStore.getFriendDelete().chatId) {
      currentChatUser.value = {};
    }
    chatUserList.value = chatUserList.value.filter((item) => {
      return item.chatId !== friendDeleteStore.getFriendDelete().chatId;
    });
    sortChatUserList(chatUserList.value);
  },
  { deep: true }
);

//置顶默认不显示
const topMsg = ref({});
const params = ref({});
//消息列表右键
const onContextMenuMessage = (item, e) => {
  ContextMenu.showContextMenu({
    x: e.x,
    y: e.y,
    items: [
      {
        icon: "icon-fuzhi",
        label: "复制",
        disabled:
          item.messageType === "text" || item.messageType === "add" ? false : true,
        onClick: () => {
          proxy.Utils.copyText(item.messageContent);
          proxy.$message.success("复制成功");
        },
      },
      {
        icon: "icon-shanchu",
        label: "删除",
        onClick: async () => {
          //过滤删除的数据
          messageList.value = messageList.value.filter((message) => {
            return message.messageId !== item.messageId;
          });
          //删除消息
          let messageDb = await openIndexedDB(
            "chat" + JSON.parse(localStorage.getItem("userInfo")).userId
          );
          deleteDB(messageDb, "message", item.messageId);
        },
      },
      {
        icon: "icon-tubiaozhizuo-",
        label: "回复",
        onClick: () => {
          replyMsgStore.setReplyMsg(item);
        },
      },
      {
        icon: "icon-zhiding",
        label: "置顶",
        onClick: async () => {
          topMsg.value = item;
          let chatDb = await openIndexedDB(
            "chat" + JSON.parse(localStorage.getItem("userInfo")).userId
          );
          const messageListDataTop = await getData(
            chatDb,
            "message",
            "chatId",
            topMsg.value.chatId
          );
          messageListDataTop
            .filter((item) => item.msgTop == 2)
            .forEach((item) => {
              item.msgTop = 1;
              updateDB(chatDb, "message", item);
            });
          const setMessageTop = await getDataByKey(chatDb, "message", item.messageId);
          setMessageTop.msgTop = 2;
          updateDB(chatDb, "message", setMessageTop);
          params.value.contactType = item.contactType;
          params.value.messageId = item.messageId;
          params.value.chatId = item.chatId;
          params.value.contactId = currentChatUser.value.contactId;
          await proxy.Api.topMessage(params.value);
        },
      },
      {
        icon: "icon-chehuisekuai",
        disabled:
          item.sendUserId === userInfoStore.getInfo().userId &&
          (new Date().getTime() - item.sendTime) / 1000 < 120
            ? false
            : true,
        label: "撤回",
        onClick: async () => {
          if ((new Date().getTime() - item.sendTime) / 1000 > 120) {
            proxy.$message.error("只能撤回2分钟内的消息");
            return;
          }
          //消息撤回这里直接做删除
          let messageDb = await openIndexedDB(
            "chat" + JSON.parse(localStorage.getItem("userInfo")).userId
          );
          deleteDB(messageDb, "message", item.messageId);
          const prefix = currentChatUser.value.contactId.substring(0, 1);
          if (prefix === "U") {
            const res = await proxy.Api.sendPrivateMessage({
              deduplicationId: proxy.UniqueId.generateUniqueUserId(),
              sendUserId: userInfoStore.getInfo().userId,
              contactId: currentChatUser.value.contactId,
              messageType: "withdraw",
              messageContent:
                "`" + userInfoStore.getInfo().username + "`" + " " + "撤回了一条消息",
              withdrawId: item.messageId,
            });
            if (res.code != 200) {
              proxy.$message.error(res.message);
              return;
            } else {
              proxy.$message.success("消息已撤回");
            }
          } else if (prefix === "G") {
            const res = await proxy.Api.sendClusterMessage({
              deduplicationId: proxy.UniqueId.generateUniqueClusterId(),
              sendUserId: userInfoStore.getInfo().userId,
              contactId: currentChatUser.value.contactId,
              messageType: "withdraw",
              messageContent:
                "`" + userInfoStore.getInfo().username + "`" + " " + "撤回了一条消息",
              withdrawId: item.messageId,
            });
            if (res.code != 200) {
              proxy.$message.error(res.message);
              return;
            } else {
              proxy.$message.success("消息已撤回");
            }
          }
        },
      },
    ],
  });
};

//回复信息详情
const messageReplyDetailRef = ref();
const getReloadReply = (data) => {
  if (data.messageType === "reply") {
    messageReplyDetailRef.value.show(data);
  }
};

//取消置顶
const topRemove = async () => {
  let chatDb = await openIndexedDB(
    "chat" + JSON.parse(localStorage.getItem("userInfo")).userId
  );
  const setMessageTop = await getDataByKey(chatDb, "message", topMsg.value.messageId);
  setMessageTop.msgTop = 1;
  updateDB(chatDb, "message", setMessageTop);
  topMsg.value = {} || undefined;
};

//置顶信息
const messageTopDetailRef = ref();
const getMessageContent = (topMsg) => {
  messageTopDetailRef.value.show(topMsg);
};

//用户会话右键
const deleteChatRef = ref();
const deleteData = ref({});
const clearChatRef = ref();
const clearData = ref({});
const onContextMenu = (data, e) => {
  // console.log("data的值：", data);
  deleteData.value = data;
  clearData.value = data;
  ContextMenu.showContextMenu({
    x: e.x,
    y: e.y,
    items: [
      {
        icon: "icon-zhiding",
        label: data.topType == 0 ? "置顶" : "取消置顶",
        onClick: () => {
          setTop(data);
        },
      },
      {
        icon: "icon-shanchu",
        label: "删除会话",
        onClick: () => {
          deleteChatRef.value.show(data);
        },
      },
      {
        icon: "icon-qingkong",
        label: "清空会话",
        onClick: () => {
          clearChatRef.value.show(data);
        },
      },
    ],
  });
};

//置顶
const setTop = async (data) => {
  data.topType = data.topType == 0 ? 1 : 0;
  sortChatUserList(chatUserList.value);
  let chatDb = await openIndexedDB(
    "chat" + JSON.parse(localStorage.getItem("userInfo")).userId
  );
  const setTopChatUser = await getDataByKey(chatDb, "chatUser", data.contactId);
  setTopChatUser.topType = data.topType;
  updateDB(chatDb, "chatUser", setTopChatUser);
};

//删除会话
const reload = () => {
  deleteChatUser(deleteData.value);
  //消息记录数要清空
  messageCountStore.setCount("chatCount", -deleteData.value.noReadCount, false);
  deleteData.value = {};
};
const deleteChatUser = async (data) => {
  //删除会话和删除聊天记录
  let chatDb = await openIndexedDB(
    "chat" + JSON.parse(localStorage.getItem("userInfo")).userId
  );
  //将用户会话状态设置为删除状态
  const setChatUserDelete = await getDataByKey(chatDb, "chatUser", data.contactId);
  setChatUserDelete.status = 2;
  updateDB(chatDb, "chatUser", setChatUserDelete);
  //删除消息记录
  cursorDelete(chatDb, "message", "chatId", data.chatId);
  //不显示该会话
  chatUserList.value = chatUserList.value.filter((item) => {
    return item.chatId !== data.chatId;
  });
  //如果是当前会话则重置为空
  if (setChatUserDelete.chatId == currentChatUser.value.chatId) {
    currentChatUser.value = {};
  }
};

//清空会话
const clearReload = async () => {
  //消息记录数要清空
  messageCountStore.setCount("chatCount", -deleteData.value.noReadCount, false);
  //会话显示已清空
  const chatUserItem = chatUserList.value.find((item) => {
    return item.chatId == clearData.value.chatId;
  });
  chatUserItem.clean = 2;
  chatUserItem.lastMessage = "已清空聊天记录";
  chatUserItem.lastReceiveTime = new Date().getTime();
  chatUserItem.lastSendName = "";
  sortChatUserList(chatUserList.value);
  //修改会话消息
  let chatDb = await openIndexedDB(
    "chat" + JSON.parse(localStorage.getItem("userInfo")).userId
  );
  const setChatUserClear = await getDataByKey(
    chatDb,
    "chatUser",
    clearData.value.contactId
  );
  setChatUserClear.clean = 2;
  setChatUserClear.lastMessage = "已清空聊天记录";
  setChatUserClear.lastReceiveTime = new Date().getTime();
  setChatUserClear.lastSendName = "";
  updateDB(chatDb, "chatUser", setChatUserClear);
  //清空该会话消息记录
  cursorDelete(chatDb, "message", "chatId", clearData.value.chatId);
  //如果是当前会话则重置为空
  if (setChatUserClear.chatId == currentChatUser.value.chatId) {
    currentChatUser.value = {};
  }
};

onMounted(() => {
  //加载转发的消息
  getMessage();
  //加载用户会话列表
  getChatUserList();
  //监听下拉分页
  nextTick(() => {
    const messagePanel = document.querySelector("#message-panel");
    messagePanel.addEventListener("scroll", (e) => {
      const scrollTop = e.target.scrollTop;
      //计算距离底部的距离
      distanceBottom = e.target.scrollHeight - e.target.clientHeight - scrollTop;
      //滚动到顶部，开始分页查询
      if (scrollTop == 0 && messageList.value.length >= 20) {
        goToMore();
      }
    });
  });
});
</script>

<style lang="scss" scoped>
.top-search {
  height: 60px;
  padding: 0px 10px;
  background: #f7f7f7;
  display: flex;
  align-items: center;
}

.chat-user-list {
  height: calc(100vh - 63px);
  overflow: auto;
  border-top: 1px solid #ddd;
}

.chat-user-list::-webkit-scrollbar {
  display: none;
}

.top {
  display: flex;
  align-items: center;
  justify-content: space-between;
  background-color: #eaeaea;

  .title-panel {
    .title {
      font-size: 13px;
      font-weight: 600;
      line-height: 60px;
      padding-left: 10px;
      color: #000000;
      flex: 1;
      text-overflow: ellipsis;
      white-space: nowrap;
    }
  }

  .icon-gengduo {
    margin-right: 10px;
    font-size: 25px;
    cursor: pointer;
  }
}

.chat-panel {
  border-top: 1px solid #ddd;
  background: #f5f5f5;

  .message-panel {
    padding: 0px 10px 0px 10px;
    height: calc(100vh - 200px - 64px - 20px);
    overflow: auto;

    .message-item {
      margin-bottom: 15px;
      text-align: center;
    }
  }

  .message-panel::-webkit-scrollbar {
    display: none;
  }

  .top-message {
    height: 19px;
    padding: 0px;
    width: 40%;
    .top-message-inner {
      background-color: #ddd;
      padding: 2px 0px 2px 15px;
      font-size: 12px;
      border-radius: 10px;
      position: relative;
      display: flex;

      .top-message-left {
        font-size: 11px;
        font-weight: 600;
        width: 80%; /* 确保文本 */
        white-space: nowrap; /* 确保文本在一行内显示 */
        overflow: hidden; /* 隐藏超出div宽度的文本 */
        text-overflow: ellipsis; /* 使用省略号表示被截断的文本 */
        cursor: pointer;
      }
      .top-message-right {
        position: absolute;
        right: 5px;
        top: 50%;
        transform: translateY(-50%);
        cursor: pointer;
        i {
          font-size: 10px;
        }
      }
    }
  }
}
</style>
